package cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.attach;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.io.FileUtil;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.module.xiaoBizHandler.config.ServerConfig;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.attach.vo.AttachRespVO;
import cn.iocoder.yudao.module.xiaoBizHandler.controller.admin.tbFile.vo.XTbFileRespVO;
import cn.iocoder.yudao.module.xiaoBizHandler.convert.attach.AttachConvert;
import cn.iocoder.yudao.module.xiaoBizHandler.convert.attach.AttachConvertCustomer;
import cn.iocoder.yudao.module.xiaoBizHandler.convert.tbFile.XTbFileConvert;
import cn.iocoder.yudao.module.xiaoBizHandler.dal.dataobject.attach.AttachDO;
import cn.iocoder.yudao.module.xiaoBizHandler.dal.dataobject.tbFile.XTbFileDO;
import cn.iocoder.yudao.module.xiaoBizHandler.service.attach.AttachService;
import cn.iocoder.yudao.module.xiaoBizHandler.utils.FileUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Api(tags = "管理后台 - 附件")
@RestController
@RequestMapping("/xiaoBizHandler/attach")
@Validated
@Slf4j
public class AttachController {


    @Resource
    AttachService attachService;

    @Autowired
    private ServerConfig serverConfig;

    @PostMapping("/upload")
    @ApiOperation("上传附件")
    public Map<String, String> uploadAttach(MultipartFile file) {
        Map<String, String> rs = new HashMap<>();
        AttachDO attachDO = attachService.uploadAttach(file);
        String id = attachDO.getId();
        String attachName = attachDO.getAttachName();
        String url = serverConfig.getUrl() + "/admin-api/xiaoBizHandler/attach/getFile?id=" + id;
        rs.put("id", id);
        rs.put("url", url);
        rs.put("name", attachName);
        rs.put("originalFilename", file.getOriginalFilename());
        rs.put("code", GlobalErrorCodeConstants.SUCCESS.getCode().toString());
        rs.put("msg", "");
        return rs;
    }

    @GetMapping("/download")
    @ApiOperation("下载附件")
    public Map<String, String> downloadAttach(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> rs = new HashMap<>();
        String path = attachService.getAttachPath(id);

        response.setCharacterEncoding("UTF-8");
        OutputStream out = null;
        File file = new File(path);
        BufferedInputStream is = null;
        byte[] b = new byte[4096];
        int len = 1024;
        // 清空response
        response.reset();
        //设置response内容的类型 普通下载类型
        response.setContentType("application/x-download");
        try {
            //设置头部信息
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            out = response.getOutputStream();
            is = new BufferedInputStream(new FileInputStream(file));
            while ((len = is.read(b)) != -1) {
                out.write(b, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                if (is != null)
                    is.close();
                if (out != null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        rs.put("code", GlobalErrorCodeConstants.SUCCESS.getCode().toString());
        rs.put("msg", "");
        return rs;
    }


    @Resource
    AttachConvertCustomer attachConvertCustomer;

    @GetMapping("/get")
    @ApiOperation("获得文件")
    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class)
    public CommonResult<AttachRespVO> getAttach(@RequestParam("id") String id) {
        AttachDO attach = attachService.getAttach(id);
        return success(attachConvertCustomer.convert(attach));
    }


    // ---------------- el-upload组件后台接口 ----------------
    @PostMapping("/uploadFile")
    @ApiOperation("上传附件")
    public Map<String, String> uploadFile(MultipartFile file) {
        Map<String, String> rs = new HashMap<>();
        AttachDO attachDO = attachService.uploadAttach(file);
        String id = attachDO.getId();
        String attachName = attachDO.getAttachName();
        rs.put("fileName", attachName);
        rs.put("url", id);
        rs.put("code", GlobalErrorCodeConstants.SUCCESS.getCode().toString());
        log.info("上传成功，文件id：" + id + "\t 文件id：" + id);
        return rs;
    }

    @GetMapping("/getFile")
    @ApiOperation("上传附件")
    public void uploadFile(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
/*        Map<String, String> rs = new HashMap<>();
        try {
            AttachDO attach = attachService.getAttach(id);
            String path = attachService.getAttachPath(id);
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, attach.getAttachName());
            FileUtils.writeBytes(path, response.getOutputStream());
            rs.put("code", GlobalErrorCodeConstants.SUCCESS.getCode().toString());
            return rs;
        } catch (IOException e) {
            log.error("下载文件失败", e);
            rs.put("code", GlobalErrorCodeConstants.FILE_DOWNLOAD_FAILED.getCode().toString());
            return rs;
        }*/

/*        id = Base64Decoder.decodeStr(id, StandardCharsets.UTF_8);
        String[] arr = id.split(",");
        id = arr[0];
        long start = Long.parseLong(arr[1]);
        long end = System.currentTimeMillis();
        long second = (end - start) / 1000;
        // 超时时间 5 秒钟
        if (second > 5)   {
            log.error("url过期，下载文件失败");
            response.setStatus(HttpStatus.GATEWAY_TIMEOUT.value());
            return;
        }*/
        AttachDO attach = attachService.getAttach(id);
        String path = attachService.getAttachPath(id);
        File file = new File(path);
        if (!file.exists()) {
            log.warn("[getFile][path({}) 文件不存在]", path);
            response.setStatus(HttpStatus.NOT_FOUND.value());
            return;
        }
        log.info("获取图片：" + attach.getAttachName());
        response.setStatus(HttpStatus.OK.value());
        ServletUtils.writeAttachment(response, path, FileUtil.readBytes(file));
    }

}
